import { createReducer } from 'reduxsauce'
import { REHYDRATE } from 'redux-persist/es/constants'

import {
  GET_SESSTIONS,
  UPDATE_ACTIVE_PATIENT_SESSION,
  GET_PATIENT_SYSTEM_MESSAGE,
  GET_NEW_BELL_ALERT_NUMBER,
  GET_BELL_ALERTS,
  BELL_ALERT_CHANGE,
  REDUCED_CHAT_NUMBER,
  GET_UN_VIEWED_CONSULTATION,
} from '@ACTIONS/message'
import { ENTER_PATIENT_SESSION } from '@ACTIONS/chat'
import { BELL_ALERT_STATUS } from '@CONSTANTS/common'
import { SET_CONSULTATION_REPORT_COUNT } from '@ACTIONS/patient'
import { REDUCED_MY_DOCTOR_MESSAGE_NUMBER } from '@ACTIONS/myDoctor'

const INITIAL_STATE = {
  sessions: [],
  loadingSessions: true,
  canLoadSessions: true,
  latestSystemMessage: null,
  refreshing: true,
  newAlertNum: 0,
  newChatMessageCount: 0,
  bellAlertList: [],
  loadingBellAlert: true,
  canLoadBellAlert: true,
  unViewedConsulReportCount: 0,
}

const rehydrate = (state, { payload }) => {
  if (payload && payload.message) {
    return { ...INITIAL_STATE, ...payload.message }
  }
  return { ...state }
}

export default createReducer(INITIAL_STATE, {
  [REHYDRATE]: rehydrate,
  [ENTER_PATIENT_SESSION.FAILURE]: (state, { error }) => ({ ...state, error }),
  [ENTER_PATIENT_SESSION.SUCCESS]: (state, { session }) => {
    const sessions = [...state.sessions]
    const sessionIndex = sessions.findIndex(se => se.SessionId === session.SessionId)
    if (sessionIndex !== -1) {
      const thisSession = sessions[sessionIndex]
      sessions[sessionIndex] = { ...thisSession, NewMessageCounts: 0 }
    }
    return {
      ...state,
      sessions
    }
  },
  [GET_SESSTIONS.FAILURE]: state => ({
    ...state,
    refreshing: false,
    loadingSessions: false
  }),
  [GET_SESSTIONS.REQUEST]: (state, { payload = {} }) => ({
    ...state,
    refreshing: payload?.skip === 0 ? true : state.refreshing,
    loadingSessions: true
  }),
  [GET_SESSTIONS.SUCCESS]: (state, { list, skip, canLoadSessions }) => {
    const sessions = skip === 0 ? list : [...state.sessions, ...list]
    return {
      ...state,
      sessions,
      refreshing: false,
      canLoadSessions,
      loadingSessions: false
    }
  },
  [GET_NEW_BELL_ALERT_NUMBER.SUCCESS]: (state, { data }) => ({
    ...state,
    newAlertNum: data.NewBellAlertCount,
    newChatMessageCount: (data.NewChatMessageCount || 0) + (data.NewFollowUpMessageCount || 0),
  }),
  [REDUCED_CHAT_NUMBER.SUCCESS]: (state, { NewMessageCounts }) => ({
    ...state,
    newChatMessageCount: Math.max(0, state.newChatMessageCount - NewMessageCounts)
  }),
  [GET_PATIENT_SYSTEM_MESSAGE.SUCCESS]: (state, { latestSystemMessage }) => ({
    ...state,
    latestSystemMessage
  }),
  [UPDATE_ACTIVE_PATIENT_SESSION.REQUEST]: (state, { updateSession }) => {
    const sessions = [...state.sessions]
    const { Participants } = state.currentSession || {}
    const prePId = Participants?.[0]?.pid
    const preDId = Participants?.[1]?.uid
    const nextPId = updateSession?.patient?.pid
    const nextDId = updateSession?.doctor?.uid
    const newMsgCount = prePId && prePId === nextPId && preDId === nextDId ? 0 : updateSession.NewMessageCounts
    const sessionIndex = sessions.findIndex(se => se.patient?.pid === nextPId && se.doctor?.uid === nextDId)
    if (sessionIndex !== -1) {
      const session = sessions[sessionIndex]
      if (session.last.createdAt > updateSession.last.createdAt) {
        // eslint-disable-next-line no-param-reassign
        updateSession = session
      }
      sessions.splice(sessionIndex, 1)
    }

    return {
      ...state,
      sessions: [{ ...updateSession, NewMessageCounts: newMsgCount }, ...sessions],
    }
  },
  [GET_BELL_ALERTS.FAILURE]: state => ({
    ...state,
    loadingBellAlert: false
  }),
  [GET_BELL_ALERTS.REQUEST]: (state, { payload = {} }) => ({
    ...state,
    bellAlertList: payload.skip === 0 ? [] : state.bellAlertList,
    loadingBellAlert: true,
  }),
  [GET_BELL_ALERTS.SUCCESS]: (state, { bellAlertList, skip, canLoadBellAlert }) => {
    const list = skip === 0 ? bellAlertList : [...state.bellAlertList, ...bellAlertList]
    return {
      ...state,
      bellAlertList: list,
      loadingBellAlert: false,
      canLoadBellAlert
    }
  },
  [BELL_ALERT_CHANGE.REQUEST]: (state, { alertId }) => {
    if (alertId.Status === BELL_ALERT_STATUS.VIEWED) return state
    const bellAlertList = [...state.bellAlertList]
    const index = bellAlertList.findIndex(item => item.AlertId === alertId)
    if (index !== -1) {
      const alert = bellAlertList[index]
      bellAlertList[index] = { ...alert, Status: BELL_ALERT_STATUS.VIEWED }
      return {
        ...state,
        bellAlertList,
        newAlertNum: Math.max(state.newAlertNum - 1, 0)
      }
    }
    return state
  },
  [GET_UN_VIEWED_CONSULTATION.SUCCESS]: (state, { count = 0 }) => ({
    ...state,
    unViewedConsulReportCount: count
  }),
  [SET_CONSULTATION_REPORT_COUNT.REQUEST]: (state, { isReduced }) => {
    if (!isReduced) return state
    return ({
      ...state,
      unViewedConsulReportCount: Math.max(state.unViewedConsulReportCount - 1, 0)
    })
  },
})
